﻿using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Linq.Expressions;
using System.Text;

namespace WorkFlowCore.Framework.Repositories
{
    public class VirtualDB
    {
        private static Dictionary<Type, List<object>> data;
        private static object _lock;
        static VirtualDB()
        {
            data = new Dictionary<Type, List<object>>();
            _lock = new object();
        }

        private static void CheckAndInit(Type type)
        {
            if (!data.ContainsKey(type))
            {
                lock (_lock)
                {
                    if (!data.ContainsKey(type))
                    {
                        data.Add(type, new List<object>());
                    }
                }
            }
        }

        public static void Init<T>(List<T> list)
        {
            Type type = typeof(T);
            CheckAndInit(type);
            data[type] = list!=null ? list.Select(t => (object)t).ToList():new List<object>();
        }

        public static void SaveData()
        {
            foreach (var item in data)
            {
                var dir = Path.Combine(Environment.CurrentDirectory, "Data");
                if (!Directory.Exists(dir)) Directory.CreateDirectory(dir);
                var path = Path.Combine(dir, item.Key.FullName);
                File.WriteAllText(path, JsonConvert.SerializeObject(item.Value), Encoding.Default);
            }
            
        }


        public static List<T> GetData<T>(Expression<Func<T, bool>> expression=null)
        {
            Type type = typeof(T);
            return data[type].Select(o => (T)o).Where(expression!=null?expression.Compile():t=>true).ToList();
        }

        public static int Add(Type type, params object[] items)
        {
            if (items != null)
            {
                var count = 0;
                foreach (var item in items)
                {
                    var list = data[type];
                    if (!list.Contains(item))
                    {
                        count++;
                        list.Add(item);
                    }
                }
                return count;
            }
            return 0;
        }
        public static int Remove(Type type,params object[] items)
        {
            if (items != null)
            {
                var count = 0;
                foreach (var item in items)
                {
                    var list = data[type];
                    if (list.Contains(item))
                    {
                        count++;
                        list.Remove(item);
                    }
                }
                return count;
            }
            return 0;
        }

        public static bool IsContains(Type type,object item)
        {
            var list = data[type];
            return list.Contains(item);
        }

        public static void ClearData()
        {
            foreach (var item in data)
            {
                item.Value.Clear();
            }
            SaveData();
        }
    }
}
